home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
MACD 5
/
MACD 5.bin
/
workbench
/
libs
/
maestixlib.lha
/
Maestix
/
demos
/
LevelWindow.s
< prev
next >
Wrap
Text File
|
1995-02-25
|
13KB
|
398 lines
*****************************************************************
* *
* maestix.library-Demo: LevelWindow *
* *
*****************************************************************
*
* Programmed by Richard Körber
* Date 1995-01-30
*
*****************************************************************
* This demonstration shows the basic receive functions of the *
* maestix library. It allocates the Maestro soundcard, select *
* the default input and displays the level of the incoming *
* signal using an intuition window. *
*****************************************************************
INCDIR "include:"
INCLUDE exec.i ; Library call macros
INCLUDE intuition.i
INCLUDE graphics.i
INCLUDE dos.i
INCLUDE maestix.i
INCLUDE libraries/maestix.i ;Reference includes
INCLUDE intuition/intuition.i
INCLUDE dos/dostags.i
INCLUDE exec/ports.i
BUFSIZE EQU 12*1024 ;size of FIFO data block
WINDOW_WIDTH EQU 50 ;width of output window
SECTION text,CODE
*---------------------------------------------------------------*
* == START OF PROGRAM == *
* *
start ;-- Open all libraries -----------------;
lea maestname(PC),a1 ;maestix
moveq #35,d0 ; V35+
exec OpenLibrary ; open
move.l d0,maestbase ; store base
beq error1 ; not found!
lea intuiname(PC),a1 ;intuition
moveq #36,d0 ; V36+
exec OpenLibrary ; open
move.l d0,intuibase ; store base
beq error2 ; not found!
lea gfxname(PC),a1 ;graphics
moveq #36,d0 ; V36+
exec OpenLibrary ; open
move.l d0,gfxbase ; store base
beq error3 ; not found!
lea dosname(PC),a1 ;dos
moveq #36,d0 ; V36+
exec OpenLibrary ; open
move.l d0,dosbase ; store base
beq error4
;-- Create buffer ----------------------;
move.l #BUFSIZE*3,d0 ;size of three buffers
move.l #$10001,d1 ;PUBLIC|CLEAR
exec AllocMem
move.l d0,buffer
beq error5
;-- Alloc signal bits ------------------;
sub.l a1,a1 ;get task ptr
exec FindTask
move.l d0,disptask
moveq #-1,d0 ;Allocate a signal bit
exec AllocSignal
move.b d0,dispsigbit
cmp.b #-1,d0 ;no signals free?
beq.w error6
moveq #-1,d0 ;Allocate a 2nd signal bit
exec AllocSignal
move.b d0,donesigbit
cmp.b #-1,d0 ;no signals free?
beq.w error7
;-- Open output window -----------------;
sub.l a0,a0 ;no newwindow struct
lea windowtags(PC),a1 ; but loads of tags
intui OpenWindowTagList
move.l d0,window
beq error8
;-- Launch level task ------------------;
move.l #tasktags,d1 ;Tags for new task
dos CreateNewProc ;create new process
tst.l d0 ;got the task?
beq error9
moveq #0,d0 ;wait 'till 2nd task setup'd
move.b donesigbit(PC),d1 ; signal
bset d1,d0
exec Wait ;wait for this event
;-- Wait for reply (main loop) ---------;
.mainloop move.l window(PC),a0 ;window message?
move.l wd_UserPort(a0),a0 ; ^message port
exec GetMsg ; try to get it...
tst.l d0 ; got one?
bne.b .gotwindow ; then evaluate it
moveq #0,d0 ;create wait mask
move.b dispsigbit(PC),d1 ; signal for re-displaying
bset d1,d0
move.l window(PC),a0 ; second, from window
move.l wd_UserPort(a0),a0 ; message port
move.b MP_SIGBIT(a0),d1 ; sig bit
bset d1,d0 ; set this bit
exec Wait ;wait for these events
move.b dispsigbit(PC),d1 ; re-display wanted?
btst d1,d0 ; test this bit
beq.b .mainloop ;not wanted -> main loop
;---- got a draw signal ----------------;
.drawsig moveq #0,d0 ;D0: x coordinate left
move leftlevel,d1 ;D1: left level
lsr #8,d1 ; (Range 0..128)
move oldleft(PC),d2 ;D2: old left level
move d1,oldleft ; store new "old" level
bsr drawlevel ;draw this level
moveq #WINDOW_WIDTH/2,d0 ;D0: x coordinate left
move rightlevel,d1 ;D1: right level
lsr #8,d1 ; (Range 0..128)
move oldright(PC),d2 ;D2: old right level
move d1,oldright ; store new "old" level
bsr drawlevel ;draw this level
bra.b .mainloop ;and do the mainloop
;---- got a window event ---------------;
.gotwindow move.l d0,a0 ;^IDCMP-message -> a0
cmp.l #IDCMP_CLOSEWINDOW,im_Class(a0) ;close window?
bne.b .mainloop ; no -> continue being idle ;)
;-- Exit program -----------------------;
exit move.l leveltask(PC),a1 ;Shut level task
moveq #0,d0
move.b levelsigbit(PC),d1
bset d1,d0
exec Signal ; signals the exit
moveq #0,d0 ;wait 'till 2nd task exited
move.b donesigbit(PC),d1 ; signal
bset d1,d0
exec Wait ;wait for this event
error9 move.l window(PC),a0 ;Close output window
intui CloseWindow
error8 move.b donesigbit(PC),d0
exec FreeSignal
error7 move.b dispsigbit(PC),d0 ;Get display task signal bit
exec FreeSignal
error6 move.l buffer(PC),a1 ;^Buffer
move.l #BUFSIZE*3,d0
exec FreeMem
error5 move.l dosbase(PC),a1 ;close dos library
exec CloseLibrary
error4 move.l gfxbase(PC),a1 ;close graphics library
exec CloseLibrary
error3 move.l intuibase(PC),a1 ;close intuition library
exec CloseLibrary
error2 move.l maestbase(PC),a1 ;close maestix library
exec CloseLibrary
error1 moveq #0,d0 ;Reply 0
rts ;back to CLI
*-------------------------------------------------------*
* drawlevel draws the level to window *
* -» D0.w x-coord *
* -» D1.w new level *
* -» D2.w old level *
* *
drawlevel movem.l a0-a4/d0-d7,-(sp) ;Store all registers
;-- evaluate "real" coordinates --------;
move.l window(PC),a4 ;^Window
moveq #0,d3 ;for calculations
move.b wd_BorderLeft(a4),d3 ;left border width
add d3,d0 ;add to x
move.b wd_BorderTop(a4),d3 ;window title height
add #128,d3 ;+128 (bottom)
neg d1 ;d3 - new level
add d3,d1
neg d2 ;d3 - old level
add d3,d2
;-- what colour to use? ----------------;
moveq #3,d3 ;use blue
cmp d2,d1 ;compare old vs. new
beq.b .done ;old = new -> leave
blo.b .colour_ok ;old > new -> blue is ok
exg d2,d1 ;old < new -> change them
moveq #0,d3 ; and use grey
.colour_ok movem.l d0-d2,-(sp) ;rescue coordinates
move d3,d0 ;set A Pen
move.l wd_RPort(a4),a1 ;^Rast Port
gfx SetAPen
movem.l (sp)+,d0-d2
;-- fill this box ----------------------;
move d2,d3 ;ymax -> D3
move d0,d2 ;xmax := xmin
add #WINDOW_WIDTH/2-1,d2 ; +bar width
move.l wd_RPort(a4),a1 ;^RastPort
gfx RectFill
;-- done -------------------------------;
.done movem.l (sp)+,a0-a4/d0-d7 ;Recall all registers
rts
*---------------------------------------------------------------*
* == LEVEL PROCESS == *
* *
LevelProc
;-- Get exiting signal -----------------;
sub.l a1,a1 ;Get task structure
exec FindTask
move.l d0,leveltask
moveq #-1,d0 ;get sig bit
exec AllocSignal
move.b d0,levelsigbit
cmp.b #-1,d0 ;got no bit
beq .error1
move.l disptask(PC),a1 ;task is done
moveq #0,d0
move.b donesigbit(PC),d1
bset d1,d0
exec Signal ; signals the exit
;-- Allocate Maestro -------------------;
sub.l a0,a0 ;no tags
maest AllocMaestro
move.l d0,maestro ;^Maestro base
beq .error2
;-- Set Modus --------------------------;
move.l maestro(PC),a0 ;^Maestro base
lea modustags(PC),a1 ;^Modus tags
maest SetMaestro ;set it now
;-- Read Status ------------------------;
move.l maestro(PC),a0 ;^Maestro base
move.l #MSTAT_Signal,d0 ;is input signal ok?
maest GetStatus ;get the card status
tst.l d0
beq .error3
;-- Create Receive-Messageport ---------;
exec CreateMsgPort ;create a messageport
move.l d0,rport ; as receive port
beq .error4
;-- Init messages ----------------------;
move.l rport(PC),d1 ;^Receive Reply Port
lea msg1(PC),a0 ;^1st Message
lea msg2(PC),a1
lea msg3(PC),a2
move.l buffer(PC),d0 ;get buffer ptr
move.l d0,(dmn_BufPtr,a0) ; set buffer1
add.l #BUFSIZE,d0
move.l d0,(dmn_BufPtr,a1) ; set buffer2
add.l #BUFSIZE,d0
move.l d0,(dmn_BufPtr,a2) ; set buffer 3
move.l #BUFSIZE,(dmn_BufLen,a0) ;Set buffer length
move.l #BUFSIZE,(dmn_BufLen,a1)
move.l #BUFSIZE,(dmn_BufLen,a2)
move.l d1,(MN_REPLYPORT,a0) ;Set Reply-Port
move.l d1,(MN_REPLYPORT,a1)
move.l d1,(MN_REPLYPORT,a2)
move #dmn_SIZEOF,(MN_LENGTH,a0) ;Set msg length
move #dmn_SIZEOF,(MN_LENGTH,a1)
move #dmn_SIZEOF,(MN_LENGTH,a2)
;-- Start receive process --------------;
move.l maestro(PC),a0 ;transmit msg to library
lea msg1(PC),a1
maest ReceiveData ; the 1st (starts receiver!)
move.l maestro(PC),a0
lea msg2(PC),a1
maest ReceiveData ; and the 2nd
move.l maestro(PC),a0
lea msg3(PC),a1
maest ReceiveData ; and the 2nd
;-- wait for messages ------------------;
.mainloop move.l rport(PC),a0 ;maestix message?
exec GetMsg ; try to get it...
tst.l d0 ; got one?
bne.b .gotmaestro ; then evaluate it
moveq #0,d0 ;create wait mask
move.b levelsigbit(PC),d1 ; signal for exiting
bset d1,d0
move.l rport(PC),a0 ; second, from receive port
move.b MP_SIGBIT(a0),d1 ; sig bit
bset d1,d0 ; set this bit
exec Wait ;wait for these events
move.b levelsigbit(PC),d1 ; exit forced?
btst d1,d0 ; test this bit
beq.b .mainloop ;not wanted -> main loop
bra.b .exit ; wanted -> leave
;---- got a maestix event --------------;
.gotmaestro bsr maestix ;evaluate it
move.l disptask(PC),a1 ;show new level
moveq #0,d0
move.b dispsigbit(PC),d1
bset d1,d0
exec Signal ; signals the exit
bra.b .mainloop ;and try again
;-- Leave task -------------------------;
.exit move.l maestro(PC),a0 ;Return all messages
maest FlushReceive
move.l rport(PC),a0 ;delete receive port
exec DeleteMsgPort
.error4 move.b levelsigbit(PC),d0 ;free signal bit
exec FreeSignal
.error3 move.l maestro(PC),a0 ;Set maestro free
maest FreeMaestro
.error2 move.l disptask(PC),a1 ;task is done
moveq #0,d0
move.b donesigbit(PC),d1
bset d1,d0
exec Signal ; signals the exit
.error1 rts ;done (freed by DOS)
*-------------------------------------------------------*
* maestix evaluate maestix event and draw level *
* -» D0.l ^Maestro Msg *
* *
maestix move.l d0,a1 ;get ptr
;-- Get pointers -----------------------;
move.l dmn_BufPtr(a1),a0 ;a0: ^received data
move.l dmn_BufLen(a1),d0
subq.l #1,d0
;-- Get left/right peak level ----------;
moveq #0,d6 ;Left maximum to here
moveq #0,d7 ;Right maximum here
.getmax move (a0)+,d1 ;get one word (left)
bpl.b .notneg_l
neg d1 ;absolute value
.notneg_l cmp d6,d1 ;new maximum?
blo.b .nxtword_l
move d1,d6 ;store as new maximum
.nxtword_l move (a0)+,d1 ;get one word (right)
bpl.b .notneg_r
neg d1 ;absolute value
.notneg_r cmp d7,d1 ;new maximum?
blo.b .nxtword_r
move d1,d7 ;store as new maximum
.nxtword_r subq.l #4,d0 ;4 bytes less...
bcc.b .getmax
move d6,leftlevel ;store new levels
move d7,rightlevel
;-- Re-send buffer to maestix ----------;
move.l maestro(PC),a0 ;Re-send message
maest ReceiveData ; to maestix library
;-- Done -------------------------------;
rts
*---------------------------------------------------------------*
* == DATA SECTION == *
* *
disptask dc.l 0 ;^Display task
leveltask dc.l 0 ;^Level task
dispsigbit dc.b 0 ;Display task signal bit
levelsigbit dc.b 0 ;Level task signal bit
donesigbit dc.b 0 ;Display task done sigbit
even
maestbase dc.l 0 ;^Maestix Lib Base
intuibase dc.l 0 ;^Intuition Lib Base
gfxbase dc.l 0 ;^Graphics Lib Base
dosbase dc.l 0 ;^DOS Lib Base
stdout dc.l 0 ;^Output FH
maestro dc.l 0 ;^Maestro Base
rport dc.l 0 ;^Receive MsgPort
buffer dc.l 0 ;^Data buffer
window dc.l 0 ;^Window structure
msg1 ds.b dmn_SIZEOF ;^first message
msg2 ds.b dmn_SIZEOF ;^second message
msg3 ds.b dmn_SIZEOF ;^third message
leftlevel dc.w 0 ;left real level
rightlevel dc.w 0 ;right real level
oldleft dc.w 0 ;old left level
oldright dc.w 0 ;old right level
modustags dc.l MTAG_Input,INPUT_STD ;use standard input
dc.l MTAG_Output,OUTPUT_BYPASS
dc.l TAG_DONE
tasktags dc.l NP_Entry,LevelProc ;<- New process' tags
dc.l NP_Priority,25
dc.l NP_Name,.name
dc.l TAG_DONE
.name dc.b "Maestix level process",0
even
windowtags dc.l WA_IDCMP,IDCMP_CLOSEWINDOW ;<- New window's tags
dc.l WA_Title,.title
dc.l WA_InnerWidth,WINDOW_WIDTH
dc.l WA_InnerHeight,129
dc.l WA_DragBar,-1
dc.l WA_DepthGadget,-1
dc.l WA_CloseGadget,-1
dc.l WA_Activate,-1
dc.l WA_RMBTrap,-1
dc.l TAG_DONE
.title dc.b "DAT Level",0
even
maestname dc.b "maestix.library",0 ;Maestix name
intuiname dc.b "intuition.library",0 ;Intuition name
gfxname dc.b "graphics.library",0 ;Graphics name
dosname dc.b "dos.library",0 ;DOS name
even
*---------------------------------------------------------------*
* == END == *
* *
END